perm filename CONCEP.25[CLS,LSP] blob
sn#847842 filedate 1987-10-30 generic text, type T, neo UTF8
\input macros
\drafttrue
\tolerance=2500
\def\bookline{\CLOS\ Specification}
\def\chapline{Programmer Interface Concepts}
\beginChapter 1.{Common Lisp Object System Specification}%
{Programmer Interface Concepts}{Programmer Interface Concepts}
This document was written by Daniel G. Bobrow, Linda G. DeMichiel,\break
Richard P. Gabriel, Sonya E. Keene, Gregor Kiczales, and David A. Moon.
Contributors to this document include Patrick Dussud, Kenneth Kahn,\break
Jim Kempf, Larry Masinter, Mark Stefik,
Daniel L. Weinreb, and Jon L White.
\endTitlePage
\beginSection{Introduction}
This proposal presents a description of the standard Programmer
Interface for object-oriented programming in the \CLOS. The first
chapter of this document describes the concepts of the \CLOS, and the
second gives an alphabetic list of the functions and macros that comprise
the \CLOS\ Programmer Interface.
A third chapter, ``The \CLOS\ Meta-Object Protocol,'' will describe how the
\CLOS\ can be customized to support other existing object-oriented
paradigms and to define new ones.
The fundamental objects of the \CLOS\ are classes, instances,
generic functions, and methods.
A {\bit class\/} object determines the structure and behavior of a set
of other objects, which are called its {\bit instances}. It is an important
feature of the \OS\ that every Common Lisp object is an {\bit
instance\/} of a class. The class of an object determines the set of
operations that can be performed on the object.
A {\bit generic function} is a function whose behavior depends on the
classes or identities of the arguments supplied to it. A generic
function object comprises a set of methods, a lambda-list, a method
combination type, and other information. The methods define the
class-specific behavior and operations of the generic function. Thus,
generic functions are objects that may be {\bit specialized} by the
definition of methods to provide class-specific operations.
A generic function chooses one or more of the set of its
methods based on the classes of its arguments.
A generic function can be used in
the same ways that an ordinary function can be used in Common Lisp; in
particular, a generic function can be used as an argument to {\bf
funcall} and {\bf apply} and stored in the function cell of a symbol.
The class-specific operations provided by generic functions are
themselves defined and implemented by {\bit methods}. A method object
contains a method function, a sequence of {\bit parameter specializers\/}
that specify when the given method is applicable, and a sequence of {\bit
qualifiers\/} that are used by the method combination facility to
distinguish among methods. Each required formal parameter of each
method has an associated parameter specializer, and the method is
expected to be invoked only on arguments that satisfy its parameter
specializers.
To summarize, a generic function is a function that contains or
encompasses a number of methods.
When a generic function is invoked, the classes of its required arguments
determine which methods might be invoked. The behavior of the generic
function results from which methods are selected for execution, the
order in which the selected methods are called, and how their values
are combined to produce the value or values of the generic function.
The {\bit method combination\/} facility controls the selection of
methods, the order in which they are run, and the values that are
returned by the generic function. The \CLOS\ offers a default method
combination type that is appropriate for most user programs. The
\CLOS\ also provides a facility for declaring new types of method
combination for programs that require them.
\endSection%{Introduction}
\beginSection{Error Terminology}
In this document, we use a terminology to describe erroneous
situations that differs from the terminology used in {\it Common Lisp:
The Language}, by Guy L. Steele Jr. In describing this terminology
we will refer to a {\bit situation}, which is the evaluation of
an expression in some specific context. For example, a situation
might be the invocation of a function on arguments that fail to
satisfy some specified constraints.
In the specification of the \CLOS, the behavior of programs in all situations
is described, and the options available to the implementor are defined; no
implementation is allowed to extend the syntax or semantics of the \OS\ except
as explicitly defined in the \OS\ specification. In particular, no
implementation is allowed to extend the syntax of the \OS\ in such a way that
ambiguity between the specified syntax of \OS\ and those extensions is
possible.
``When situation $S$ occurs an error is signaled.''
The meaning of this terminology is:
\beginlist
\item{\bull} If this situation occurs, an error will be signaled in code
compiled under all compiler safety optimization levels and in the
interpreter.
\item{\bull} Valid programs may rely on the fact that an error will
be signaled in code compiled under all compiler safety optimization levels
and in the interpreter.
\item{\bull} Every implementation is required to detect such an error in
code compiled under all compiler safety optimization levels and in the
interpreter.
\endlist
``When situation $S$ occurs an error should be signaled.''
The meaning of this terminology is:
\beginlist
\item{\bull} If this situation occurs, an error will be signaled at
least in code compiled under the safest compiler safety optimization
level and in the interpreter.
\item{\bull} Valid programs may not rely on the fact that an error will be
signaled.
\item{\bull} Every implementation is required to detect such an error
at least in code compiled under the safest compiler safety
optimization level and in the interpreter.
\item{\bull} When an error is not signaled, the results are undefined (see
below).
\endlist
``When situation $S$ occurs the results are undefined.''
The meaning of this terminology is:
\beginlist
\item{\bull} If this situation occurs, the results are unpredictable. The
results may range from harmless to fatal to the running system.
\item{\bull} No valid program should cause this situation to happen.
\item{\bull} Implementations are allowed to detect this situation and
signal an error, but no implementation is required to detect the
situation.
\item{\bull} No implementation is allowed to extend the semantics of the
\OS\ to this situation; the effects of the situation may be harmless, but
they must remain undefined.
\endlist
``The \CLOS\ may be extended to cover situation $S$.''
The meaning of this terminology is that an implementation is free to treat
situation $S$ in one of three ways:
\beginlist
\item{\bull} When situation $S$ occurs, an error is signaled at least
in code compiled under the safest compiler safety optimization level
and in the interpreter.
\item{\bull} When situation $S$ occurs, the results are undefined.
\item{\bull} When situation $S$ occurs, the results are defined and
specified.
\endlist
In addition, this terminology means that:
\beginlist
\item{\bull} No portable program can depend on the effects of this
situation, and all portable programs are required to treat the situation
as undefined.
\endlist
``Implementations are free to extend the syntax $S$.''
The meaning of this terminology is:
\beginlist
\item{\bull} Implementations are allowed to define unambiguous extensions
to that syntax.
\endlist
The \CLOS\ specification may disallow certain extensions while allowing others.
\endSection%{Error Terminology}
\beginSection{Classes}
A {\bit class\/} is an object that determines the structure and behavior
of a set of other objects, which are called its {\bit instances}.
A class can inherit structure and behavior from other classes.
A class whose definition refers to other classes for the purpose of
inheriting from them is said to be a {\bit subclass\/} of each of
those classes. The classes that are designated for purposes of
inheritance are said to be {\bit superclasses\/}
of the inheriting class.
A class can have a {\bit name}, which is a symbol. The function {\bf
class-name} takes a class object and returns its name. The name of an
anonymous class is {\bf nil}. The function {\bf symbol-class} takes a
symbol and returns the class associated with that symbol. We say that a
class~$C$ has the {\bit proper name}~$S$ if
$S=$ {\tt (class-name $C$)} and
$C=$ {\tt (symbol-class $S$)}. Notice that it is possible that
$C'\neq$ {\tt (symbol-class (class-name $C'$))} for some class $C'$.
We say that a class, $C\sub{1}$, is a {\bit direct superclass\/} of
a class, $C\sub{2}$, if $C\sub{2}$ explicitly designates
$C\sub{1}$ as a superclass in its definition.
We say that $C\sub{2}$ is a {\bit direct subclass\/} of $C\sub{1}$.
We will say that a class
$C\sub{n}$ is a {\bit superclass\/} of a class $C\sub{1}$ if there
exists a series of classes $C\sub{2},\ldots,C\sub{n-1}$ such that
$C\sub{i+1}$ is a direct superclass of $C\sub{i}$ for $1 \leq i<n$.
In this case, we say that $C\sub{1}$ is a {\bit subclass\/} of
$C\sub{n}$. A class is considered neither a superclass nor a subclass of itself. That
is, if $C\sub{1}$ is a superclass of $C\sub{2}$, then $C\sub{1} \neq
C\sub{2}$. We refer to the set of classes consisting of some given
class $C$ along with all of its superclasses as ``$C$ and its superclasses.''
When a class is defined, the order in which its direct superclasses
are mentioned in the defining form is important. Each class has a
{\bit local precedence order\/}, which is a list consisting of the
class followed by its direct superclasses in the order mentioned
in the defining form.
Each class has a {\bit class precedence list}, which is a total ordering
on the set of the given class and its superclasses. The total ordering
is expressed as a list ordered from most specific to least specific.
The class precedence list is used in several ways. In general, more
specific classes can {\bit shadow}, or override, features that would
otherwise be inherited from less specific classes. The method selection
and combination process uses the class precedence list to order methods
from most specific to least specific.
A class precedence list is always consistent with the local precedence
order of each class in the list. The classes in each local precedence
order appear within the class precedence list in the same order. If
the local precedence orders are inconsistent with each other, no class
precedence list can be constructed, and an error will be signaled.
The class precedence list and its computation is discussed at
length in the section ``Determining the Class Precedence List.''
Classes are organized into a {\bit directed acyclic graph}. There is
a distinguished class named {\bf t}. The class {\bf t} has no
superclasses. It is a superclass of every class except itself.
There is a mapping from the Common Lisp type space
into the Common Lisp Object System class space. Many of the standard
Common Lisp types specified in {\it Common Lisp: The Language\/}
have a corresponding class that has the same proper name as the
type. Some Common Lisp types do
not have a corresponding class. The integration of the type and class
system is discussed later in this chapter.
Classes are represented by first-class objects that are themselves
instances of classes. The class of the class of an object is termed
the {\bit metaclass\/} of that object. When no misinterpretation is
possible, we will also use the term {\bit metaclass\/} to refer to a
class that has instances that are themselves classes. The metaclass
determines the form of inheritance used by the classes that are its
instances and the representation of the instances of those classes.
The \CLOS\ provides a default metaclass, {\bf standard-class}, that is
appropriate for most programs. The meta-object protocol will allow
for defining and using new metaclasses.
\beginsubSection{Defining Classes}
The macro {\bf defclass} is used to define a new class. The syntax for
{\bf defclass} is given in Figure~2-1.
The definition of a class includes:
\beginlist
\item{\bull} The proper name of the new class.
\item{\bull} The list of the direct superclasses of the new class.
\item{\bull} A set of slot specifiers. Each slot specifier includes the name
of the slot and zero or more slot options. A slot option pertains only to a
single slot.
\item{\bull} A set of class options. Each class option pertains
to the class as a whole.
\endlist
The slot options and class options of the {\bf defclass} form allow for
the following:
\beginlist
\item{\bull} Providing a default initial value form for a given slot.
\item{\bull} Requesting that methods for generic functions
be automatically generated for reading or writing one or more slots.
\item{\bull} Controlling whether one copy of a given slot is
shared by instances or whether each instance has its own copy of that
slot.
\item{\bull} Providing a set of initialization arguments and initialization
argument defaults to be used in instance creation.
%\item{\bull} Requesting that a constructor function be automatically
%generated for making instances of the new class.
\item{\bull} Indicating that the instances of the class are to have a
metaclass other than the default.
\endlist
A class definition cannot contain two slot specifiers with the same name.
\endsubSection%{Defining Classes}
\beginsubSection{Creating Instances of Classes}
The generic function {\bf make-instance} creates and returns a new
instance of a class. The \OS\ provides a flexible means for specifying
how a new instance is to be initialized. For example, it is possible to
specify the initial values for slots in newly-created instances either by
giving arguments to {\bf make-instance} or by providing default
initial values. Further initialization activities can be performed by
methods written for generic functions that are part of the initialization
protocol. The complete initialization protocol is described in the
section ``Object Creation and Initialization.''
\endsubSection%{Creating Instances of Classes}
\beginsubSection{Slots}
An object has zero or more named slots. The slots of an object are
determined by the class of the object. Each slot can hold one value.
The name of a slot is a symbol that can be used as a Common Lisp
variable name.
When a slot does not have a value, we say that the slot is {\bit
uninitialized} (see the function {\bf slot-boundp}). When an
uninitialized slot is read, the generic function {\bf slot-unbound} is
invoked.
We define a {\bit local slot} to be a slot that is visible to exactly one
instance, namely the one in which the slot is allocated. We define a
{\bit shared slot} to be a slot that is visible to a subset of the
instances of a given class and its subclasses. Often this subset is the
same as the set of instances of the class and its subclasses, but a
smaller subset can result if a subclass redefines the slot.
We say that a class {\bit defines\/} a slot with a given name when
the {\bf defclass} form for that class contains a slot specifier with
that name. Defining a local slot does not immediately create a slot;
it causes a slot to be created each time an instance of the class is
created. Defining a shared slot creates a slot.
The {\bf :allocation} slot option controls the kind of slot that is
defined. If the value of the {\bf :allocation} slot option is {\bf
:instance}, a local slot is created.
This is the most commonly
used kind of slot. If the value of {\bf :allocation} is {\bf :class}, a
shared slot is created.
We say that a slot is {\bit accessible\/} in an instance of a class if
the slot is defined by the class of the instance or is inherited from
a superclass of that class. At most one slot of a given name can be
accessible in an instance. A detailed explanation of the inheritance
of slots is given in the section ``Inheritance of Slots and Slot
Options.''
\endsubSection%{Slots}
\beginsubSection{Accessing Slots}
Slots can be accessed in two ways: by use of generic functions defined by
the {\bf defclass} form and by use of the primitive function
{\bf slot-value}.
The {\bf defclass} syntax allows for generating methods to read and
write slots. If an {\bit accessor\/} is requested, a method is
automatically generated for reading the value of the slot, along with
a method for storing a value into the slot. If a {\bit reader\/} is
requested, a method is automatically generated for reading the value
of the slot, but no method for storing a value into it is generated.
These methods are added to the appropriate generic functions. Readers
and accessors are implemented by using {\bf slot-value}. When a
reader or accessor is specified for a slot, the name of the generic
function is directly specified. If {\it accessor} is the name
specified for the reader part of an accessor generic function, the
name of the writer part is {\tt (setf {\it accessor})}. It is possible
to modify the behavior of these generic functions by writing methods
for them.
The function {\bf slot-value} can be used with any of the slot names
specified in the {\bf defclass} form to access a specific slot in an
object of the given class. Note that {\bf slot-value} can be used to
read or write the value of a slot whether or not accessor
functions exist for that slot. When {\bf slot-value} is used, no
methods for the accessors are called.
The macro {\bf with-slots} can be used to establish a lexical
environment in which certain slots are lexically available as if they
were variables. The macro {\bf with-slots} invokes the function {\bf
slot-value} to access the slots.
\endsubSection%{Accessing Slots}
\endSection%{Classes}
\beginSection{Inheritance}
Inheritance is the key to program modularity within the \CLOS. A typical
object-oriented program consists of several classes, each of which
defines some aspect of behavior. New classes are defined by including
the appropriate classes as superclasses, thus gathering desired aspects
of behavior into one class.
A class can inherit slots and some {\bf defclass} options from
its superclasses. This section describes what
is inherited from superclasses and how a class can shadow an aspect
of inherited behavior.
\beginsubSection{Inheritance of Methods}
A subclass inherits methods in the sense that any method applicable to
an instance of a class is also applicable to instances of any subclass
of that class (all other arguments to the method being the same).
The inheritance of methods acts the same way regardless of whether the
method was created by using {\bf defmethod} or by using one of the
{\bf defclass} options that cause methods to be generated
automatically.
The inheritance of methods is described in detail in the section
``Method Selection and Combination.''
\endsubSection%{Inheritance of Methods}
\beginsubSection{Inheritance of Slots and Slot Options}
The set of the names of all slots accessible in an instance of a class
$C$ is the union of the sets of names of slots defined by $C$ and its
superclasses.
In the simplest case, only one class among $C$ and its superclasses
defines a slot with a given slot name. If a slot is defined by a
superclass of $C$, we say that the slot is inherited. The characteristics
of the slot are determined by the slot specifier of the defining class.
Consider the defining class for a slot $S$. If the {\bf :allocation} slot
option is omitted or its value is {\bf :instance}, then $S$ is a local
slot and each instance of $C$ has its own slot named $S$ that stores its
own value. If the value of the {\bf :allocation} slot option is {\bf
:class}, then $S$ is a shared slot, the class that defined $S$ stores the
value, and all instances of $C$ can access that single slot.
In general, more than one class among $C$ and its superclasses can define
a slot with a given name. In such cases, only one slot with the given
name is accessible in an instance of $C$, and the characteristics of that
slot are a combination of the several slot specifiers, computed as
follows:
\beginlist
\item{\bull} All the slot specifiers for a given slot name are ordered
from most specific to least specific, according to the order in the class
precedence list of $C$ of the classes that define them.
\item{\bull} The allocation of a slot is controlled by the most specific
slot specifier. If the most specific slot specifier does not contain an
{\bf :allocation} slot option, {\bf :instance} is used. Less specific
slot specifiers never affect the allocation.
\item{\bull} The effective value for the {\bf :initform} option of a slot
is controlled by the most specific slot specifier that contains an {\bf
:initform} slot option. If no slot specifier contains an {\bf :initform}
slot option, the slot has no default initial value form.
\item{\bull} The contents of a slot will always be of type {\tt
(and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are
the values of the {\bf :type} slot options contained in all of the slot
specifiers. If no slot specifier contains the {\bf :type} slot option, the
contents of a slot will always be of type {\bf t}. Attempting to store
a value in a slot that does not satisfy the type should signal
an error.
\item{\bull} The set of initialization arguments that initialize a given
slot is the union of the initialization arguments declared in the {\bf
:initarg} slot options in all the slot specifiers.
\endlist
A consequence of the allocation rule is that a shared slot can be
shadowed. For example, if a class $C\sub 1$ defines a slot named $S$
whose value for the {\bf :allocation} slot option is {\bf :class}, that
slot is accessible in instances of $C\sub 1$ and all of its subclasses.
However, if $C\sub 2$ is a subclass of $C\sub 1$ and also defines a slot
named $S$, $C\sub 1$'s slot is not shared by instances of $C\sub 2$ and
its subclasses.
A consequence of the type rule is that the value of a slot satisfies the
type constraint of each slot specifier that contributes to that slot.
Because an implementation is required to check the type of the value
being stored in a slot only under the safest compiler safety setting and in the
interpreter, a value in a slot might fail to satisfy its type contraint.
The {\bf :reader} and {\bf :accessor} slot options create methods rather
than define the characteristics of a slot. Reader and accessor
methods are inherited in the sense described in the section ``Inheritance
of Methods.''
Methods that access slots know only the name of the slot and the type of
the slot's value. Suppose a superclass provides a method that expects
to access a shared slot of a given name and a subclass defines a local
slot with the same name. If the method provided by the superclass is
used on an instance of the subclass, the method accesses the local slot.
\beginsubSection{Inheritance of Class Options}
The {\bf :default-initargs} class option is inherited. The set of
defaulted initialization arguments for a class is the union
of the sets of initialization arguments specified in {\bf
:default-initargs} class options of the class and its superclasses.
When more than one default value form is supplied for a given
initialization argument, the default value form supplied by the class
that appears earliest in the class precedence list is used; if that
class contains more than one such default value form, the one that
appears leftmost in the {\bf defclass} form is selected.
\endsubSection%{Inheritance of Class Options}
\vfill\eject
\beginsubSection{Examples of Inheritance}
\screen!
(defclass C1 ()
((S1 :initform 5.4 :type number)
(S2 :allocation :class))
(defclass C2 (C1)
((S1 :initform 5 :type integer)
(S2 :allocation :instance)
(S3 :accessor C2-S3)))
\endscreen!
Instances of the class {\tt C1} have a local slot named {\tt S1}, whose default
initial value is 5.4 and whose value will always be a number.
{\tt C1} also has a shared slot named {\tt S2}.
There is a local slot named {\tt S1} in instances of {\tt C2}. The
default initial value of {\tt S1} is 5. The value of {\tt S1} will be
of type {\tt (and integer number)}. There are also local slots named
{\tt S2} and {\tt S3} in instances of {\tt C2}. The class {\tt C2} has
a method for reading the value of slot {\tt S3} in instances of the class;
there is also a method for {\bf setf} of {\tt C2-S3} that writes the
value of {\tt S3}.
\endsubSection%{Examples of Inheritance}
\endSection%{Inheritance}
\beginSection{Redefining Classes}
When a {\bf defclass} form is evaluated and a class with the given
name already exists, the existing class is redefined. Redefining a
class modifies the existing class object to reflect the new class
definition; it does not create a new class object for the class. Any
method created by an {\bf :accessor} or {\bf :reader}
option specified by the old
{\bf defclass} form is removed from the corresponding generic
function unless that same method is specified by the new {\bf
defclass} form; any function specified by the {\bf :constructor}
option of the old {\bf defclass} form is removed from the
corresponding symbol function cell.
When the class $C$ is redefined, changes are propagated to instances
of it and to instances of any of its subclasses. Updating an
instance whose class has been redefined (or any of whose superclasses
have been redefined) occurs at an implementation-dependent time, but
no later than the next time a slot of that instance is read or written.
Updating an instance does not change its identity as
defined by the {\bf eq} function. The updating process may change the
slots of that particular instance, but it does not create a new
instance. Whether updating an instance consumes storage is
implementation-dependent.
Note that redefining a class may cause slots to be added or deleted.
If a class is redefined in such a way that the set of local
slots accessible in an instance is the same and the order of slots
in storage is unchanged, no actions are taken.
If a class is redefined in such a way that the set of local slots
accessible in an instance of the class is changed or the order of
slots in storage is changed, a two-step process of updating the
instances of the class takes place. The first step changes the
structure of the instance to conform to the new class definition,
leaving newly-added slots uninitialized and discarding deleted slots;
the second step initializes these slots and performs any other
user-defined actions. The second step is implemented by a generic
function, {\bf update-instance-structure}, which is called after
completion of the first step of updating the instance.
Implementations may choose to invoke {\bf update-instance-structure}
under other circumstances as well. When {\bf
update-instance-structure} is called, the structure of the instance
has already been converted to conform to the new class definition, and
newly-added slots are uninitialized.
The default primary method for {\bf update-instance-structure}
performs initialization on the newly-added slots. Each local slot of
the new version of the class with no slot by the same name in the old
version of the class is initialized to the value of the corresponding
{\bf :initform} option of the new class or remains uninitialized if
the new version of the class does not specify or inherit the {\bf
:initform} option for that slot. This is the same as the
initialization done by {\bf make-instance} except that no
initialization methods are invoked and no {\bf make-instance}
initialization arguments are present. Methods for {\bf
update-instance-structure} can be defined to specify actions to be
taken when an instance is updated, and if these methods are {\bf
:after} methods, they will be invoked after the initialization
performed by the default primary method.
If in the new version of the class there is a local slot of the same
name as any slot in the old version of the class, the value of that
slot is unchanged. This is true regardless of whether the old slot
was a local slot or a shared slot. This means that if the slot
has a value, the value returned by {\bf slot-value} after
class redefinition is {\bf eql} to the value returned by {\bf
slot-value} before class redefinition. Similarly, if the
slot was uninitialized, it remains uninitialized.
If in the new version of the class there is a shared slot of the same
name as any shared slot in the old version of the class, the value of
that slot is unchanged. If in the new version of the class there is a
shared slot of the same name as any local slot in the old version of
the class, that shared slot is initialized to the value of the
corresponding {\bf :initform} option of the new class or remains
uninitialized if the new version of the class does not specify or
inherit the {\bf :initform} option for that slot. Shared slots are
updated at the moment of class redefinition and are not affected by
the updating of an instance nor by the values of any local slots.
The \OS\ guarantees that {\bf defclass} can be used to change the
definition of an existing class that was previously defined by {\bf
defclass} as long as in each definition the {\bf :metaclass} option is
either not used or is specified as the class {\bf standard-class}.
Whether {\bf defclass} is allowed to change the metaclass and whether
redefining a class causes existing instances to be updated is up to
the implementor of the particular metaclass. ``The \CLOS\ Meta-Object
Protocol'' will describe how to control this.
\endSection%{Redefining Classes}
\beginSection{Changing the Class of an Instance}
The function {\bf change-class} can be used to change the class of an
instance from its current class, $C\sub {\hbox{{\prmseven from}}}$, to a
different class, $C\sub {\hbox{{\prmseven to}}}$; it changes the
structure of the instance to conform to the definition of the class
$C\sub {\hbox{{\prmseven to}}}$.
Note that changing the class of an instance may cause slots to be
added or deleted. When an instance is changed, new slots are
initialized and the values of deleted slots are discarded by {\bf
change-class}.
If in changing the class of an instance, either the set of local slots
accessible in the instance or the order of slots in storage is
changed, a two-step process of updating the instances of the class
takes place. The first step modifies the structure of the instance to
conform to the new class definition, leaving newly-added slots
uninitialized and discarding deleted slots; the second step
initializes these slots and performs any other user-defined actions.
The second step is implemented by a generic function, {\bf
class-changed}, which is called after completion of the first step of
updating the instance. Implementations may choose to invoke {\bf
class-changed} under other circumstances as well. When {\bf
class-changed} is called, the structure of the instance has already
been converted to conform to the new class definition, and newly-added
slots are uninitialized.
The default primary method for {\bf class-changed}
performs initialization on the newly-added slots. Each local slot of
the new version of the class with no slot by the same name in the old
version of the class is initialized to the value of the corresponding
{\bf :initform} option of the new class or remains uninitialized if
the new version of the class does not specify or inherit the {\bf
:initform} option for that slot. This is the same as the
initialization done by {\bf make-instance} except that no
initialization methods are invoked and no {\bf make-instance}
initialization arguments are present. Methods for {\bf
class-changed} can be defined to specify actions to be
taken when an instance is updated, and if these methods are {\bf
:after} methods, they will be invoked after the initialization
performed by the default primary method.
If in the class $C\sub {\hbox{{\prmseven to}}}$ there is a local slot of
the same name as any slot in the class $C\sub {\hbox{{\prmseven
from}}}$, the value of that slot is unchanged. This means that if the
slot has a value, the value returned by {\bf slot-value} after {\bf
change-class} is invoked is {\bf eql} to the value returned by {\bf
slot-value} before {\bf change-class} is invoked. Similarly, if the
slot was uninitialized, it remains uninitialized.
Each local slot of the class $C\sub {\hbox{{\prmseven to}}}$ with no
slot by the same name in the class $C\sub {\hbox{{\prmseven from}}}$ is
initialized to the value of the corresponding {\bf :initform} option
of the class $C\sub {\hbox{{\prmseven to}}}$ or remains uninitialized if
the class $C\sub {\hbox{{\prmseven to}}}$ does not specify or inherit an
{\bf :initform} option for that slot.
After {\bf change-class} has completed the first step of the update,
it invokes the generic function {\bf class-changed} on two arguments
computed by {\bf change-class}. The first argument passed is a copy of
the instance being updated and is an instance of the class $C\sub
{\hbox{{\prmseven from}}}$; this copy has dynamic extent within the
generic function {\bf class-changed}. The second argument is the
instance as updated so far by {\bf change-class} and is an instance of
the class $C\sub {\hbox{{\prmseven to}}}$. Methods for {\bf
class-changed} can be written to perform other activities whenever an
instance of one class is made to be an instance of another class.
\endSection%{Changing the Classes of an Instance}
\beginSection{Integrating Types and Classes}
The \CLOS\ maps the Common Lisp type space into the space of classes.
Every class that has a proper name has a corresponding type with the same
name. The {\bf defclass} and {\bf defstruct} constructs define both
types and classes.
The proper name of every class is a valid type specifier. In addition, every
class object is a valid type specifier. Thus the expression {\tt (typep
{\it object class\/})} evaluates to true if the class of {\it object\/}
is {\it class\/} itself or a subclass of {\it class}. The evaluation of
the expression {\tt (subtypep {\it class1 class2\/})} returns the
values {\bf t t} if {\it class1\/} is a subclass of {\it class2\/} or if they
are the same class; otherwise it returns the values {\bf nil t}.
If $I$ is an instance of some class $C$
named $S$, the evaluation of the
expression {\tt (type-of $I$)} will return $S$ if $S$ is the proper
name of $C$, otherwise it will return $C$.
Because class names and class objects are type specifiers, they can
be used in {\bf the} special forms and in type declarations.
Many but not all of the predefined Common Lisp type specifiers have a
corresponding class with the same proper name as the type. For
example, the type {\bf array} has a corresponding class named {\bf
array}. A class that corresponds to a predefined Common Lisp type is
called a {\bit standard type class\/}. Each standard type class has
the class {\bf standard-type-class} as a metaclass. The \CLOS\ may be
extended to allow making an instance of a standard type class with
{\bf make-instance} or including a standard type class as a
superclass of a class.
The purpose of specifying that many of the standard Common Lisp types
have a corresponding class is to allow users to write methods that
discriminate on these types.
Method selection requires that a class precedence list can be
determined for each class. This list orders the class and its superclasses
from most to least specific.
The hierarchical relationships among
the Common Lisp types are maintained by the classes corresponding to
those types. Thus the existing type hierarchy is used for determining
the class precedence lists for each standard type class.
In some cases, {\it Common Lisp: The
Language\/} does not specify a subtype/supertype relationship for two
supertypes of a given type. For example, {\bf null} is a subtype of
both {\bf symbol} and {\bf list}, but {\it Common Lisp: The Language\/}
does not specify whether {\bf symbol} is more or less specific than {\bf
list}. The \CLOS\ specification defines those relationships for all
standard type classes.
The following table lists the set of standard type classes required by
\CLOS. The superclasses of each standard type class are presented in
order from most specific to most general, according to the class precedence
list for the class.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil\hfil\tabskip \dimen0 plus .5 fil&\hfil\cr %was &
\noalign{\vskip -9pt}
\hfil\bf Standard Type Class&\bf Class Precedence List\span\omit\span\omit\cr
\noalign{\vskip 2pt\hrule\vskip 2pt}
array&t\cr
bit-vector&vector, array, sequence, t\cr
character&t\cr
complex&number, t\cr
cons&list, sequence, t\cr
float&number, t\cr
integer&rational, number, t\cr
list&sequence, t \cr
null&symbol, list, sequence, t\cr
number&t\cr
ratio&rational, number, t\cr
rational&number, t\cr
sequence&t\cr
string&vector, array, sequence, t\cr
symbol&t\cr
t\cr
vector&array, sequence, t\cr
\noalign{\vskip -9pt}
}}
\caption{}
\endfig
Note that instances of standard-type classes are disjoint with all other
types.
Individual implementations can allow other type specifiers to have a
corresponding class. Individual implementations can also add additional
subclass relationships as long as they do not violate the type
relationships specified by {\it Common Lisp: The Language\/}.
Creating a type by means of {\bf defstruct} also creates a class in the
space of Common Lisp classes. Such a class is an instance of {\bf
structure-class} and a direct subclass of the class that corresponds to
the included structure, if any.
No type specifier that is a list, such as {\tt (vector double-float
100)}, has a corresponding class. No type defined by {\bf deftype} has
a corresponding class.
%For a discussion on some of the design decisions underlying this aspect
%of \CLOS\, see the section ``Design Theories of the Integration of Types
%and Classes''.
\endSection%{Integrating Types and Classes}
\beginSection{Determining the Class Precedence List}
The {\bf defclass} form for a class provides a total ordering on that
class and its direct superclasses. This ordering is called the {\bit
local precedence order\/}. It is an ordered list of the class and its
direct superclasses. A class precedes its direct superclasses, and a
direct superclass precedes all other direct superclasses specified to
its right in the superclasses list of the {\bf defclass} form. For
every class $C$ we define $$R\sub C=\{(C,C\sub 1),(C\sub 1,C\sub
2),\ldots,(C\sub {n-1},C\sub n)\}$$ where $C\sub 1,\ldots,C\sub n$ are
the direct superclasses of $C$ in the order in which
they are mentioned in the {\bf defclass} form. These ordered pairs
generate the total ordering on the class $C$ and its direct
superclasses.
Let $S\sub C$ be the set of $C$ and its superclasses. Let $R$ be
$$R=\bigcup\sub{c\in {S\sub C}}R\sub c$$
The set $R$ may or may not generate a partial ordering, depending on
whether the $R\sub c$, $c\in S\sub C$, are consistent; we assume they
are consistent and that $R$ generates a partial ordering. When the
$R\sub c$ are not consistent we say that $R$ is inconsistent. This
partial ordering is generated by taking the the transitive closure of
the set $R\cup \{(c,c) \vert c\in {S\sub C}\}$. When $(C\sub 1,C\sub
2)\in R$, we say that $C\sub 1$ {\bit precedes or equals} $C\sub 2$.
Intuitively, $C\sub 1$ precedes or equals $C\sub 2$ when $C\sub
1=C\sub 2$ or $C\sub 2$ is a superclass of $C\sub 1$. In the remainder of
this section we will use the set of precedence relations $R$ and not
the partial ordering.
To compute the class precedence list at~$C$, we topologically sort the
elements of $S\sub C$ with respect to the partial ordering generated
by $R$. When the topological sort must select a class from a set of
two or more classes, none of which are preceded by other classes with
respect to~$R$, the class selected is chosen deterministically, as
described below.
We require that an implementation of \CLOS\ signal an error if
$R$ is inconsistent, that is, if the class precedence list cannot be
computed.
\beginsubSection{Topological Sorting}
Topological sorting proceeds by finding a class $C$ in~$S\sub C$ such
that no other class precedes that element according to the elements
in~$R$. The class $C$ is placed first in the result. We remove $C$
from $S\sub C$, and we remove all pairs of the form $(C,D)$, $D\in
S\sub C$, from $R$. We repeat the process, adding classes with no
predecessors at the end of the result. We stop when no element can be
found that has no predecessor.
If $S\sub C$ is not empty and the process has stopped, the set $R$ is
inconsistent: if every class in the finite set of classes is preceded
by another, then $R$ contains a loop. That is, there are two classes,
$C\sub 1$ and $C\sub 2$, and a chain of classes $C\sub {i\sub
1},\ldots,C\sub {i\sub n}$ such that $C\sub {i\sub
k}\thinspace\hbox{precedes}\thinspace C\sub{i\sub {k+1}}$, $1\leq k<{i\sub
n}$, where ${C\sub 1}={C\sub {i\sub 1}}={C\sub {i\sub n}}$ and ${C\sub
2}={C\sub {i\sub j}}$ for some $1<i<n$.
Sometimes there are several classes from $S\sub C$ with no
predecessors. In this case we select the one that has a direct
subclass rightmost in the class precedence list computed so far.
Because a direct superclass precedes all other direct superclasses to
its right, there can be only one such candidate class. If there is no
such candidate class, $R$ does not generate a partial ordering---the
$R\sub c$, $c\in S\sub C$, are inconsistent.
In more precise terms, let $\{N\sub 1,\ldots,N\sub m\}$, $m\geq 2$, be
the classes from $S\sub C$ with no predecessors. Let $(C\sub
1\ldots C\sub n)$, $n\geq 1$, be the class precedence list
constructed so far. $C\sub 1$ is the most specific class and $C\sub
n$ is the least specific. Let $1\leq j\leq n$ be the largest number
such that $\exists \thinspace i$ where $1\leq i\leq m$ and $N\sub i$
is a direct superclass of $C\sub j$; $N\sub i$ is placed next.
The effect of this rule for selecting from a set of classes with no
predecessors is that each simple superclass chain and each relatively
separated subgraph is kept together in the class precedence list. For
example, let $T\sub 1$ and $T\sub 2$ be subgraphs whose only element
in common is the class {\bf t}; let $C\sub 1$ be the bottom of $T\sub
1$; and let $C\sub 2$ be the bottom of $T\sub 2$. Suppose $C$ is a
class whose direct superclasses are $C\sub 1$ and $C\sub 2$ in that
order, then the class precedence list for $C$ will start with $C$ and
will be followed by all classes in $T\sub 1$ except {\bf t}; after all
the classes of $T\sub 1$ will be all classes in $T\sub 2$.
\endsubSection%{Topological Sorting}
\beginsubSection{Examples}
Here is an example of determining a class precedence list for the
class {\tt pie}. The classes are defined:
\screen!
(defclass pie (apple cinnamon) ())
(defclass apple (fruit) ())
(defclass cinnamon (spice) ())
(defclass fruit (food) ())
(defclass spice (food) ())
(defclass food () ())
\endscreen!
The set $S$~$=$ $\{${\tt pie, apple, cinnamon, fruit, spice, food, t}$\}$. The
set $R$~$=$ $\{${\tt (pie, apple),
(apple, cinnamon), (apple, fruit), (cinnamon, spice),
(fruit, food), (spice, food),\break
(food, t)}$\}$.
The class {\tt pie} is not preceded by anything, so it comes first;
the result so far is {\tt (pie)}. We remove {\tt pie} from $S$ and
pairs mentioning {\tt pie} from $R$ and get $S$~$=$ $\{${\tt
apple, cinnamon, fruit, spice, food, t}$\}$ and $R$~$=$ $\{${\tt
(apple, cinnamon), (apple, fruit), (cinnamon, spice),
(fruit, food), (spice, food), (food, t)}$\}$.
The class {\tt apple} is not preceded by anything, so it is next; the
result is {\tt (pie apple)}. Removing {\tt apple} and the relevant
pairs we get $S$~$=$ $\{${\tt cinnamon, fruit, spice, food, t}$\}$ and
$R$~$=$ $\{${\tt (cinnamon, spice), (fruit, food),
(spice, food), (food, t)}$\}$.
The classes {\tt cinnamon} and {\tt fruit} are not preceded by
anything, so we look at which of these two has a direct subclass
rightmost in the class precedence list computed so far. The class
{\tt apple} is a direct subclass of {\tt fruit} and is rightmost in
the precedence list. Therefore, we select {\tt fruit} next, and the
result so far is {\tt (pie apple fruit)}. $S$~$=$ $\{${\tt cinnamon,
spice, food, t}$\}$; $R$~$=$ $\{${\tt (cinnamon, spice), (spice,
food), (food, t)}$\}$.
The class {\tt cinnamon} is next, giving the result so far as {\tt (pie apple
fruit cinnamon)}. $S$~$=$ $\{${\tt spice, food, t}$\}$; $R$~$=$
$\{${\tt (spice, food), (food, t)}$\}$.
The classes {\tt spice}, {\tt food}, and {\tt t} are added in that
order, and the class precedence list is {\tt (pie apple fruit cinnamon
spice food t)}.
It is possible to write a set of class definitions that cannot be
ordered. For example:
\screen!
(defclass new-class (fruit apple) ())
(defclass apple (fruit) ())
\endscreen!
The class {\tt fruit} must precede {\tt apple} because the local
ordering of superclasses is preserved. The class {\tt apple} must
precede {\tt fruit} because a class always precedes its own
superclasses. When this situation occurs, an error is signaled when
the system tries to compute the class precedence list.
Note the following example, which appears at first glance to be a
conflicting set of definitions:
\screen!
(defclass pie (apple cinnamon) ())
(defclass pastry (cinnamon apple) ())
(defclass apple () ())
(defclass cinnamon () ())
\endscreen!
The class precedence list for {\tt pie} is {\tt (pie apple cinnamon t)}.
The class precedence list for {\tt pastry} is {\tt (pastry cinnamon apple t)}.
There is no problem with the fact that {\tt apple} precedes {\tt
cinnamon} in the ordering of the superclasses of {\tt pie} but does not in the
ordering for {\tt pastry}. However, it is not possible to build a new class
that has both {\tt pie} and {\tt pastry} as superclasses.
\endsubSection%{Examples}
\endSection%{Determining the Class Precedence List}
\beginSection{Generic Functions and Methods}
\beginsubSection{Introduction to Generic Functions}
A generic function object comprises a set of methods, a
lambda-list, a method combination type, and other information.
Like an ordinary Lisp function, a generic function takes arguments,
performs a series of operations, and perhaps returns useful values. An
ordinary function has a single body of code that is always executed
when the function is called. A generic function might perform a
different series of operations and combine the results of the
operations in different ways, depending on the class or identity of
one or more of its arguments. A generic function can have several
methods associated with it, and the class or identity of each
argument to the generic function indicates which method or
methods to use.
Ordinary functions and generic functions are called with identical
syntax.
Generic functions are true functions that can be passed as arguments and
used as the first argument to {\bf funcall} and {\bf apply}.
Ordinary functions have a definition that is in one place; generic
functions have a distributed definition. The definition of a generic
function can be found in a set of {\bf defmethod} forms, possibly along
with a {\bf defgeneric} form that provides information about the
behavior of the generic function. Evaluating these forms produces a
generic function object.
In Common Lisp, a name can be given to an ordinary function in one of
two ways: a {\bit global\/} name can be given to a function using the
{\bf defun} construct; a {\bit local\/} name can be given using the
{\bf flet} or {\bf labels} special forms. A generic function can be
given a global name using the {\bf defmethod} or {\bf defgeneric}
constructs. A generic function can be given a local name using the
{\bf generic-flet}, {\bf generic-labels}, or {\bf with-added-methods}
special forms. The name of a generic function, like the name of an
ordinary function, can be either a symbol or a two-element list whose
first element is {\bf setf} and whose second element is a symbol.
This is true for both local and global names.
The {\bf generic-flet} special form creates a new local generic function
with the set of methods specified by its method definitions. The scoping
of generic function names within a {\bf generic-flet} form is the same as for
{\bf flet}.
The {\bf generic-labels} special form creates a new local generic function
with the set of methods specified by its method definitions. The scoping
of generic function names within a {\bf generic-labels} form is the same as for
{\bf labels}.
The {\bf with-added-methods} special form creates a new local generic
function by adding the set of methods specified by its method
definitions to copies of the methods of the lexically visible generic
function of the same name. If there is a lexically visible ordinary function,
that function becomes the method function of the default method
for the new generic function.
The {\bf generic-function} special form creates an anonymous generic
function with the set of methods specified by its method definitions.
When a new {\bf defgeneric} form is evaluated and a generic
function of the given name already exists, the existing generic function
object is modified. This does not modify any of the methods associated
with the generic function. When a {\bf defgeneric} form is
evaluated and no generic function of the given name exists, a generic
function is created with the methods specified by its method definitions.
The macro {\bf defmethod} is used to create a method object. Both
{\bf defmethod} and {\bf defgeneric} use {\bf symbol-function} to find
the generic function that they affect. When a generic function is
associated with a symbol, that name is in a certain package and can be
exported if desired.
Some forms enable one to specify the options of a generic function,
such as the type of method combination it uses or its argument
precedence order. These forms will be referred to as ``forms that
specify generic function options.'' These forms are: {\bf defgeneric},
{\bf generic-function}, {\bf generic-flet}, {\bf generic-labels}, and
{\bf with-added-methods}.
Some forms enable one to define methods for a generic function. These
forms will be referred to as ``method-defining forms.'' These forms are:
{\bf defgeneric}, {\bf defmethod}, {\bf generic-function}, {\bf
generic-flet}, {\bf generic-labels}, and {\bf with-added-methods}.
\endsubSection%{Introduction to Generic Functions}
\beginsubSection{Introduction to Methods}
A method object contains a method function, a sequence of {\bit parameter
specializers\/} that specify when the given method is applicable, and
a sequence of {\bit qualifiers\/} that are used by the method combination
facility to distinguish among methods.
A method-defining form contains the code that is to be run when the
arguments to the generic function cause the method that it defines to
be selected. When a method-defining form is evaluated and a generic
function of the given name already exists, then one of two things
happens:
\beginlist
\item{\bull} If a method object with the same
parameter specializers and qualifiers already exists, the
new method replaces the old one.
\item{\bull} Otherwise, the existing generic function object is
modified to contain the new method. The lambda-list of the new method
must be congruent with the lambda-list of the generic function or else
an error is signaled.
\endlist
When a method-defining form is evaluated and no generic function with that
name exists, a generic function is created with default values for the
argument precedence order, the generic function class, the method class,
and the method combination type. The lambda-list of the generic function
is derived from the lambda-list of the new method and is, hence, congruent.
For a discussion of {\bit congruence}, see the section ``Congruent
Lambda-lists for All Methods of a Generic Function.''
Each method has a {\bit specialized lambda-list}, which determines
when that method can be selected. A specialized lambda-list is like
an ordinary lambda-list except that a {\bit specialized parameter\/}
may occur instead of the name of a required parameter. A specialized parameter
is a list, {\tt ({\it variable-name parameter-specializer-name\/})},
where {\it parameter-specializer-name\/} is one of the following:
\beginlist
\item{\bull} The name of any class
\item{\bull} {\tt ({\bf eql} {\it form\/})}
\endlist
A parameter specializer name denotes a parameter specializer as follows:
\beginlist
\item{\bull} The name of a class denotes the class object
\item{\bull} The form {\tt ({\bf eql} {\it form\/})} denotes {\tt
({\bf eql} {\it object\/})}, where {\it object\/} is the result of
evaluating {\it form\/}. The form {\it form\/} is evaluated in the
lexical environment in which the method-defining form was evaluated.
Note that {\it form\/} is evaluated only once, at the time the method
is defined, not each time the generic function is called.
\endlist
Parameter specializer names are used in macros intended as the
user-level interface ({\bf defmethod}), while parameter specializers
are used in the functional interface to method creation ({\bf
make-instance} of {\bf standard-method} and {\bf get-method}).
Only required parameters can be specialized, and there must be a
parameter specializer for each required parameter. For notational
simplicity, if some required parameter in a specialized lambda-list is
simply a variable name, its parameter specializer defaults to the
class named {\bf t}.
Given a generic function and a set of arguments, an {\bit applicable
method\/} is a method for that generic function whose parameter
specializers are satisfied by their corresponding arguments. The
following is a definition of what it means for an argument to satisfy
a parameter specializer.
Let $\langle A\sub 1, \ldots, A\sub n\rangle$ be the required arguments
to a generic function in order. Let $\langle P\sub 1, \ldots, P\sub
n\rangle$ be the parameter specializers corresponding to the required
parameters of the method $M$ in order. The method $M$ can be selected
when each $A\sub i$ satisfies $P\sub i$. If $P\sub i$ is a class, and
if $A\sub i$ is an instance of a class $C$, then we say that $A\sub i$
satisfies $P\sub i$ when $C=P\sub i$ or when $C$ is a subclass of $P\sub i$.
If $P\sub i$ is {\tt ({\bf eql} {\it object})}, then we say that
$A\sub i$ satisfies $P\sub i$ when $A\sub i$ is {\bf eql} to {\it
object}.
This proposal requires that parameter specializers be Common Lisp type
specifiers.
Because a parameter specializer is a type specifier, the function {\bf
typep} can be used to determine whether an argument satisfies a
parameter specializer during method selection. Thus, this standard
includes an upward-compatible extension of the Common Lisp type system
and does not create another type system. Note that in general a
parameter specializer cannot be a type specifier list, such as {\tt
({\bf vector single-float})}. The only parameter specializer that can
be a list is {\tt ({\bf eql} {\it object\/})}.
This proposal requires that Common Lisp be modified to include
{\tt ({\bf deftype eql} ({\it object\/}) `({\bf member} {\it ,object\/}))}.
A method all of whose parameter specializers are the class named {\bf
t} is a {\bit default method\/}; it is always applicable but often
shadowed by a more specific method.
Methods can have {\bit qualifiers}, which give the method combination
procedure a way to distinguish between methods. A method that has one
or more qualifiers is called a {\bit qualified\/} method.
A method with no qualifiers is called an {\bit unqualified method}.
A qualifier is any object other than a list, that is,
any non-{\bf nil} atom. By convention, qualifiers are usually
symbols, but it is possible to use a vector used as a qualifier.
In this specification, the terms {\bit primary method\/} and {\bit
auxiliary method\/} are used to partition methods within a method
combination type according to their intended use. In standard method
combination, primary methods are unqualified methods and auxiliary
methods are methods with a single qualifier that is {\bf :around},
{\bf :before}, or {\bf :after}. When a method combination type is
defined using the short form of {\bf define-method-combination},
primary methods are defined to include not only the methods qualified
with the name of the type of method combination, but certain others as
well. Thus, the terms {\bit primary method\/} and {\bit auxiliary
method\/} have only a relative definition within a given method
combination type.
\endsubSection%{Introduction to Methods}
\beginsubSection{Congruent Lambda-lists for All Methods of a Generic Function}
These rules define the congruence of a set of lambda-lists, including the
lambda-list of each method for a given generic function and the
lambda-list specified for the generic function itself, if given.
\beginlist
\item{1.} Each lambda-list must have the same number of required
parameters.
\item{2.} Each lambda-list must have the same number of optional
parameters. Each method can supply a different default for an optional
parameter.
\item{3.} If any lambda-list mentions {\bf \&rest} or {\bf \&key}, each
lambda-list must mention one or both of these.
\item{4.} If the generic function lambda-list mentions {\bf \&key}, each
method must accept all of the keyword names mentioned after {\bf \&key},
either by accepting them explicitly, by specifying {\bf
\&allow-other-keys}, or by specifying {\bf \&rest} but not {\bf \&key}.
Each method can accept additional keyword arguments of its own. The
checking of the validity of keyword names is done in the generic
function, not in each method.
\item{5.} The use of {\bf \&allow-other-keys} need not be consistent
across lambda-lists. If {\bf \&allow-other-keys} is mentioned in any
lambda-list, then any keyword arguments may be mentioned in the call to the
generic function.
\item{6.} The use of {\bf \&aux} need not be consistent across methods.
\endlist
\endsubSection%{Congruent Lambda-lists for All Methods of a Generic Function}
\beginsubSection{Keyword Arguments in Generic Functions and Methods}
When a generic function or any of its methods mentions {\bf \&key} in
a lambda-list, the specific set of keyword arguments accepted by the
generic function varies according to the applicable methods. The
keyword arguments accepted by the generic function for a particular call
are the union of the keyword arguments accepted by all applicable
methods and the keyword arguments mentioned after {\bf \&key} in the
generic function definition, if any. There is no attempt to exclude
methods that are applicable but are not actually called. A method
that has {\bf \&rest} but not {\bf \&key} does not affect the set of
acceptable keyword arguments. If the lambda-list of any applicable
method or of the generic function definition contains {\bf
\&allow-other-keys}, all keyword arguments are accepted by the generic
function.
The lambda-list congruence rules require that each method accept all of
the keyword arguments mentioned after {\bf \&key} in the generic function
definition, by accepting them explicitly, by specifying {\bf
\&allow-other-keys}, or by specifying {\bf \&rest} but not {\bf \&key}.
Each method can accept additional keyword arguments of its own, in addition
to the keyword arguments mentioned in the generic function definition.
For example, suppose there are two methods defined for {\tt width}
as follows:
\screen!
(defmethod width ((c character) &key font) ...)
(defmethod width ((p picture) &key pixel-size) ...)
\endscreen!
\noindent Assume that there are no other methods and no generic
function definition for {\tt width}. Then the evaluation of the
following form should signal an error unless {\tt x} is both a
character and a picture. The acceptable arguments are determined by
the applicable methods, not by all methods of the generic function.
\screen!
(width x :font 'baskerville :pixel-size 10)
\endscreen!
\endsubSection%{Keyword Arguments in Generic Functions and Methods}
\endSection%{Generic Functions and Methods}
\beginSection{Method Selection and Combination}
When a generic function is called with particular arguments, it must decide
what code to execute. We call this code the {\bit effective method\/} for
those arguments. The effective method can be one of the methods for the
generic function or a combination of several of them. If a generic function
is called and no methods apply, the generic function {\bf no-applicable-method}
is invoked.
When the effective method has been determined, it is called with the same
arguments that were passed to the generic function. Whatever values it
returns are returned as the values of the generic function.
Choosing the effective method involves the following decisions:
\beginlist
\item{\bull} Which method or methods to call
\item{\bull} The order in which to call the methods
\item{\bull} Which method to call when {\bf call-next-method} is invoked
\item{\bull} Which value or values to return
\endlist
\beginsubSection{Determining the Effective Method}
The effective method is determined by the following three-step procedure:
\beginlist
\item{1.}{Select the set of applicable methods.}
\item{2.}{Sort the applicable methods by precedence order, putting
the most specific method first.}
\item{3.}{Apply method combination to the sorted list of
applicable methods, producing the effective method.}
\endlist
\beginsubsubsection{Sorting the Applicable Methods by Precedence Order}
To compare the precedence of two methods, examine their parameter
specializers in order. The default examination order is from left to
right, but an alternative order may be specified by the {\bf
:argument-precedence-order} option to {\bf defgeneric} or any of the
other forms that specify generic function options.
Compare the corresponding parameter specializers from each method. When
a pair of parameter specializers are equal, proceed to the next pair and
compare them for equality. If all corresponding parameter specializers
are equal, the two methods must have different qualifiers; in this case,
either method can be selected to precede the other. If some
corresponding parameter specializers are not equal, the first pair of
parameter specializers that are not equal determines the precedence.
If both parameter specializers are classes, consider the class
precedence list of the class of the argument. The more specific of
the two methods is the method whose parameter specializer appears
earlier in the class precedence list. Because of the way in which the
set of applicable methods is chosen, the parameter specializers are
guaranteed to be present in the class precedence list of the class of
the argument.
If just one parameter specializer is {\tt ({\bf eql} {\it
object\/})}, the method with that parameter specializer precedes the
other method. If both parameter specializers are {\bf eql}
forms, the
specializers must be equal (otherwise the two methods would
not both have been applicable for this argument).
The resulting list of applicable methods has the most specific
method first and the least specific method last.
\endsubsubsection%{Sorting the Applicable Methods by Precedence Order}
\beginsubsubsection{Applying Method Combination to the Sorted List of Applicable Methods}
In the simple case---if standard method combination is used and all
applicable methods are primary methods---the effective method is the
most specific method. That method can call the next most specific
method by using the function {\bf call-next-method}. The method that
{\bf call-next-method} will call is referred to as the {\bit next method}.
In general, the effective method is some combination of the applicable
methods. It is defined by a Lisp form that contains calls to some or
all of the applicable methods, returns the value or values to be
returned by the generic function, and optionally makes some of the
methods accessible by means of {\bf call-next-method}. This Lisp form
is the body of the effective method; it is augmented with an
appropriate lambda-list to make it a function.
Method qualifiers determine the role of each method in the effective
method. The meaning of the qualifiers of a method is defined entirely by
this step of the procedure. If an applicable method has an unrecognized
qualifier, this step signals an error and does not include that method in
the effective method.
When standard method combination is used together with qualified methods,
the effective method is produced as described in the section
``Standard Method Combination.''
The programmer can select another type of method combination by using
the {\bf :method-combination} option of {\bf defgeneric} or of any of
the other forms that specify generic function options. This allows
the programmer to customize this step of this procedure without having
to consider what happens in the other steps.
New types of method combination can be defined using the
{\bf define-method-combination} macro.
\goodbreak
The meta-object level also offers a mechanism for defining new types
of method combination. The generic function {\bf
compute-effective-method} receives as arguments the generic function,
the sorted list of applicable methods, the name of the method
combination type, and the list of options specified in the {\bf
:method-combination} option. It returns
the Lisp form that defines the effective method. The programmer can
define a method for {\bf compute-effective-method} directly by using
{\bf defmethod} or indirectly by using {\bf define-method-combination}.
\endsubsubsection
\beginImplNote
In the simplest implementation, the generic function would compute the
effective method each time it was called. In practice, this might be
too inefficient for most implementations. Instead, these
implementations might employ a variety of optimizations of the
three-step procedure, such as precomputation into tables, compilation,
and/or caching to speed things up. Some illustrative examples of
such optimizations are the following:
\beginlist
\item{\bull} Use a hash table keyed by the class of the arguments to
store the effective method.
\item{\bull} Compile the effective method and save the resulting
compiled function in a table.
\item{\bull} Recognize the Lisp form as an instance of a pattern of
control structure and substitute a closure that implements
that structure.
\item{\bull} Examine the parameter specializers of all methods for the
generic function and enumerate all possible effective methods.
Combine the effective methods, together with code to select from
among them, into a single function and compile that function. Call
that function whenever the generic function is called.
\endlist
\endImplNote
The Lisp form computed by Step~3 as the body of the effective method serves
as a more general interface. For example, a tool that determines which
methods are called and presents them to the user works by going through the
first three steps of the above procedure and then by analyzing the form to
determine which methods it calls instead of by evaluating it.
Separating the procedure of determining the effective method from the
procedure of invoking methods and combining their results
enables more optimizations
to the speed of the code and enables more powerful programming tools
to be written.
\endsubSection%{Determining the Effective Method}
\vfill\eject
\beginsubSection{Standard Method Combination}
Standard method combination is used if either no other type of method
combination or the built-in method combination type {\bf
standard} is specified. Standard method
combination recognizes four roles for methods, as determined by method
qualifiers.
{\bit Primary methods\/} define the main action of the effective method,
while {\bit auxiliary methods\/} modify that action in one of three ways.
A primary method has no method qualifiers.
The auxiliary methods are {\bf :before}, {\bf :after}, and {\bf :around}
methods.
\beginlist
\item{\bull}
A {\bf :before} method has the keyword {\bf :before} as its
only qualifier. A {\bf :before} method specifies code that is to be
run before any primary methods.
\item{\bull}
An {\bf :after} method has the keyword {\bf :after} as its only
qualifier. An {\bf :after} method specifies code that is to be run
after primary methods.
\item{\bull}
An {\bf :around} method has the keyword {\bf :around} as its only
qualifier.
\endlist
The semantics of standard method combination are:
\beginlist
\item{\bull} If there are any {\bf :around} methods, the most specific
{\bf :around} method is called. It supplies the value or values of the
generic function.
\item{\bull}
Inside the body of an {\bf :around} method, {\bf call-next-method} can
be used to immediately call the next method. When the next method
returns, the {\bf :around} method can execute more code, perhaps based
on the returned value or values. By convention, {\bf :around} methods
almost always use {\bf call-next-method}.
\item{\bull}
If an {\bf :around} method invokes {\bf call-next-method}, the next
most specific {\bf :around} method is called, if one is applicable.
If there are no {\bf :around} methods or if {\bf
call-next-method} is called by the least specific {\bf :around}
method, the other methods are called as follows:
\itemitem{--} All the {\bf :before} methods are called, in
most-specific-first order. Their values are ignored.
\itemitem{--}
The most specific primary method is called. Inside the body of a
primary method, {\bf call-next-method} may be used to pass control
to the next most specific primary method. When that method returns,
the first primary method can execute more code, perhaps based on the
returned value or values. An error is signaled if {\bf
call-next-method} is used and there is no applicable primary method to
call. The function {\bf next-method-p} may be used to determine whether a
next method exists. If {\bf call-next-method} is not used, only
the most specific primary method is called.
\itemitem{--} All the {\bf :after} methods are called in
most-specific-last order. Their values are ignored.
\item{\bull}
If no {\bf :around} methods were invoked, the most specific primary
method supplies the value or values returned by the generic function.
Otherwise, the value or values returned by the most specific primary
method are those returned by the invocation of
{\bf call-next-method} in the least specific {\bf :around} method.
\endlist
In standard method combination, if there are any applicable methods at
all, then there must be an applicable primary method. In cases where
there are applicable methods, but no primary method, an error is
signaled.
An error is signaled if {\bf call-next-method} is used and there is no
next method remaining.
An error is signaled if {\bf call-next-method} is used in a {\bf :before}
or {\bf :after} method.
Standard method combination allows no more than one qualifier per method.
Running {\bf :before} methods in most specific first order while
running {\bf :after} methods in least specific first order provides a
degree of transparency. If class $C \sub 1$ modifies the behavior of
its superclass, $C \sub 2$, by adding an auxiliary method, the
partitioning of $C \sub 2$'s behavior into primary, {\bf :before}, and
{\bf :after} methods is transparent. Whether class $C \sub 2$ defines
these methods directly or inherits them from its superclasses is
transparent. Class $C \sub 1$'s {\bf :before} method runs before
all of class $C \sub 2$'s methods. Class $C \sub 1$'s {\bf :after}
method runs after all of class $C \sub 2$'s methods.
The {\bf :around} methods are an exception to this rule; they do not combine
transparently. All {\bf :around} methods run before any other methods
run. Thus, a less specific {\bf :around} method runs before a more specific
primary method.
If only primary methods are used, standard method combination behaves like
CommonLoops. If {\bf call-next-method} is not used, only the most specific
method is invoked; that is, more general methods are shadowed by more
specific ones. If {\bf call-next-method} is used, the effect is the same
as {\bf run-super} in CommonLoops.
If {\bf call-next-method} is not used, standard method combination behaves
like {\bf :daemon} method combination of New Flavors, with {\bf :around}
methods playing the role of whoppers, except that the ability to reverse
the order of the primary methods has been removed.
\endsubSection%{Standard Method Combination}
\beginsubSection{Declarative Method Combination}
The programmer can define new forms of method combination by using
the {\bf define-method-combination} macro. This allows customization
of Step~3 of the method combination procedure described in the
section ``Determining the Effective Method.'' There are two forms
of {\bf define-method-combination}. The short form is a simple
facility for the cases that have been found to be
most commonly needed.
The long form is more powerful but more verbose. It resembles
{\bf defmacro} in that the body is an expression that computes
a Lisp form, usually using backquote. Thus, arbitrary control
structures can be implemented. The long form also allows arbitrary
processing of method qualifiers.
The syntax and use of both forms of {\bf define-method-combination} is
explained in the second chapter of this document.
\endsubSection%{Declarative Method Combination}
\goodbreak
\beginsubSection{Built-in Method Combination Types}
The \CLOS\ provides a set of built-in method combination types. To
specify that a generic function is to use one of these method
combination types, the name of the method combination type is given as
the argument to the {\bf :method-combination} option to {\bf
defgeneric} or to any of the other forms that specify generic
function options.
These method combination types act as though they were defined by the
short form of {\bf define-method-combination}. They recognize two
roles for methods.
\beginlist
\item{\bull}
An {\bf :around} method has the keyword symbol {\bf :around} as its sole
qualifier. The semantics of {\bf :around} methods are the same as in
standard method combination. Use of the function {\bf call-next-method}
is supported in {\bf :around} methods.
\item{\bull}
A primary method has the name of the method combination type as its
sole qualifier. For example, the built-in method combination type {\bf and}
recognizes methods whose sole qualifier is {\bf and}; these are primary
methods. Use of the function {\bf call-next-method} is not supported
in primary methods.
\endlist
Each of the built-in method combination types is named after a Lisp
operator, which can be a function, special form, or macro. The
effective method combines all of the applicable primary methods in
a call to the Lisp operator with the same name as the
method combination type. That is, the method combination type
produces a Lisp form
$$\hbox{{\tt ({\it operator method-call method-call $\ldots$ })}}$$
The names of the built-in method combination types are
{\bf +}, {\bf and}, {\bf append}, {\bf list}, {\bf max}, {\bf min},
{\bf nconc}, {\bf or}, {\bf progn}, and {\bf standard}.
The semantics of these types of method combination are as follows:
\beginlist
\item{\bull}
If there are any {\bf :around} methods, the most specific {\bf :around}
method is called. It supplies the value or values of the generic function.
\item{\bull}
Inside the body of an {\bf :around} method, the function {\bf call-next-method}
can be used to immediately call the next method. When the next method returns,
the {\bf :around} method can execute more code, perhaps based on the returned
value or values. By convention, {\bf :around} methods almost always use
{\bf call-next-method}.
\item{\bull}
If an {\bf :around} method invokes {\bf call-next-method}, the next most
specific {\bf :around} method is called, if one is applicable. If there
are no {\bf :around} methods or if {\bf call-next-method} is called by the
least specific {\bf :around} method, the Lisp operator corresponding to
the method combination type is called. By default the order of
the primary methods is {\bf :most-specific-first}. However, the order
can be reversed by supplying {\bf :most-specific-last} as the second argument
to the {\bf :method-combination} option.
\endlist
An error is signaled if {\bf call-next-method} is used in a primary method.
An error is signaled if there are no applicable primary methods.
\eject
These types of method combination require exactly one qualifier per
method. An error is signaled if there are applicable methods with no
qualifiers, or with qualifiers that are not supported by the method
combination type.
\endsubSection%{Built-in Method Combination Types}
\endSection%{Method Selection and Combination}
\beginSection{Meta Objects}
\beginsubSection{Metaclasses}
The {\bit metaclass\/} of an object is the class of its class. The
metaclass determines the form of inheritance used by its classes and the
representation of the instances of its classes. The metaclass mechanism
can be used to provide particular forms of optimization or to tailor the
\CLOS\ for particular uses (such as the implementation of other object
languages like Smalltalk-80, Loops, and CommonObjects).
Any new metaclass must define the structure of its instances, how their
storage is allocated, how their slots are accessed, and how slots and
methods are inherited. The protocol for defining metaclasses will be
discussed in Chapter~3, ``The \CLOS\ Meta-Object Protocol.''
\endsubSection
\beginsubSection{Standard Metaclasses}
The \CLOS\ provides a number of predefined metaclasses. These
include the following: {\bf standard-class},
{\bf standard-type-class}, and {\bf structure-class}.
\beginlist
\item{\bull}
The class {\bf standard-class} is the default class of classes defined
by {\bf defclass}.
\item{\bull} The class {\bf standard-type-class} is a metaclass of all
the classes that correspond to the standard Common Lisp types
specified in {\it Common Lisp: The Language\/} by Guy L. Steele Jr.
%These types are listed in Figure~1-1.
The \CLOS\ may be extended to
allow {\bf make-instance} of a standard-type class or to allow
inclusion of a standard type class as a superclass of a class.
\item{\bull}
The class {\bf structure-class} is a subclass of {\bf standard-type-class}.
All classes defined by means of {\bf defstruct} are instances of
{\bf structure-class} or a subclass of {\bf structure-class}.
\endlist
\endsubSection%{Standard Metaclasses}
\beginsubSection{Standard Meta-Objects}
The \CLOS\ provides the predefined meta-objects
{\bf standard-method} and {\bf standard-generic-function}.
\beginlist
\item{\bull}
The class {\bf standard-method} is the default class of methods
defined by {\bf defmethod}.
\item{\bull}
The class {\bf standard-generic-function} is the default class of
generic functions defined by {\bf defmethod},
{\bf defgeneric}, {\bf generic-function}, {\bf generic-flet},
{\bf generic-labels}, and {\bf with-added-methods}.
\endlist
The \CLOS\ also provides several predefined method combination types.
\endsubSection%{Standard Meta-Objects}
\endSection%{Meta-Objects}
\beginSection{Object Creation and Initialization}
The generic function {\bf make-instance} creates and returns a new
instance of a class. The first argument is a class or the name of a
class, and the remaining arguments form an {\bit initialization argument}
list.
Initialization consists of several distinct steps, including the
following: combining the explicitly supplied initialization arguments
with default values for the unsupplied initialization arguments,
checking the validity of the initialization arguments, allocating
storage for the instance, filling slots with values, and executing
user-supplied methods that perform additional initialization. The
\OS\ defines {\bf make-instance} in a procedural way: each step is
represented by a generic function. This provides a mechanism for
customizing each step. In addition, {\bf make-instance} is itself a generic
function and thus can also be customized.
The \OS\ specifies default methods for each step, and thus creates a
well-defined standard behavior for the entire initialization
procedure. The standard behavior provides four simple mechanisms for
controlling initialization:
\beginlist
\item{\bull} Declaring a symbol to be an initialization argument for a
slot. An initialization argument is declared by using the {\bf
:initarg} slot option to {\bf defclass}. This allows one to provide a
value for a slot in a call to {\bf make-instance}.
\item{\bull} Supplying a default value form for an initialization
argument. Default value forms for initialization arguments are defined
by using the {\bf :default-initargs} class option to {\bf defclass}. A default
value is used if the initialization argument is not explicitly provided as
an argument to {\bf make-instance}.
\item{\bull} Supplying a default value form for a slot. A default value
form for a slot is defined by using the {\bf :initform} slot option to
{\bf defclass}. This default value is stored in the slot if no
initialization argument associated with that slot is given as an argument
to {\bf make-instance} or is defaulted by {\bf :default-initargs}.
\item{\bull} Defining methods for {\bf initialize-instance}. The
slot-filling behavior described above is implemented by a system-supplied
default method for {\bf initialize-instance}. Additional control over
initialization can be obtained by writing methods for {\bf
initialize-instance}. In most cases {\bf :after} methods are appropriate
for this purpose, because they are called after the default method that
fills the slots and thus do not override the normal slot-filling behavior.
\endlist
Note that the object creation and initialization procedure can be
controlled at two different levels. The standard behavior offers the four
mechanisms mentioned above; this level can be considered the Programmer
Interface level. At the meta-object level, greater control can be exerted
over each step of this procedure; this level can be considered the
interface for experimentation with alternative object-oriented paradigms.
There is one general guideline that helps distinguish between the
Programmer Interface and the meta-object levels of programming. To
customize initialization behavior at the Programmer Interface level,
methods that specialize on instances are written. That is, the
arguments that select methods are instances. To customize
initialization behavior at the meta-object level, methods that
specialize on classes are written. That is, the arguments that select
methods are classes.
\beginsubSection{Initialization Arguments}
An initialization argument can be used to control
object creation and initialization. The {\bf \&key} arguments to {\bf
make-instance} are initialization arguments. It is often convenient to
use keyword symbols to name initialization arguments, but the name of an
initialization argument can be any symbol, including {\bf nil}. An
initialization argument can be used in two ways: to fill a slot with a value
or to provide an argument for an initialization method. A single
initialization argument can be used for both purposes.
An {\bit initialization argument list} is a list of alternating
initialization argument names and values. Its structure is identical to a
property list and also identical to the portion of an argument list
processed for {\bf \&key} parameters. As in those lists, if an
initialization argument name appears more than once in an initialization
argument list, the leftmost occurrence supplies the value and the
remaining occurrences are ignored. The arguments to {\bf make-instance}
(after the first argument) are an initialization argument list. As in an
{\bf \&key} argument list, {\bf :allow-other-keys} can appear in an
initialization argument list. If its value is non-{\bf nil},
error-checking of initialization argument names is disabled.
An initialization argument can be associated with a slot. If the
initialization argument has a value in the initialization argument
list, the value is stored into the slot of the newly-created object,
overriding any {\bf :initform} form associated with the slot. A
single initialization argument can initialize more than one slot. An
initialization argument that initializes a shared slot stores its
value into the shared slot, replacing any previous value.
An initialization argument can be associated with a method.
Such an initialization argument is intended as an argument for one or more
methods for {\bf initialize-instance} or {\bf allocate-instance}. When an
object is created, the method is called with the initialization argument's
name and value as a keyword argument, and the method uses the value however
it chooses. If a value for the initialization argument is not supplied in
the initialization argument list, the method's lambda-list supplies a default
value.
\endsubSection%{Initialization Arguments}
\beginsubSection{Declaring the Validity of Initialization Arguments}
The generic function {\bf make-instance} checks the validity of its
initialization arguments and signals an error if an initialization
argument is supplied that is not declared as valid.
Initialization arguments that fill slots are declared as valid by the {\bf
:initarg} slot option to {\bf defclass}. The {\bf :initarg} slot option
is inherited from superclasses. Thus, the set of valid initialization
arguments that fill slots for a class is the union of the initialization
arguments declared by the class and its superclasses.
Initialization arguments that supply arguments to methods are declared as
valid by defining methods for {\bf initialize-instance} or {\bf
allocate-instance}. The keyword name of each keyword parameter specifier
in the method's lambda-list becomes an initialization argument for all
classes for which the method is applicable. Thus, method inheritance
controls the set of valid initialization arguments that supply arguments
to methods.
The set of valid initialization arguments for a class is the set of valid
initialization arguments that either fill slots or supply arguments to
methods along with the predefined initialization argument {\bf
:allow-other-keys}. The default value for {\bf :allow-other-keys} is
{\bf nil}. The behavior of {\bf :allow-other-keys} is the same as when it is
passed to a function in Common Lisp.
\endsubSection%{Declaring the Validity of Initialization Arguments}
\beginsubSection{Defaulting of Initialization Arguments}
A {\bit default value form} can be supplied for an initialization
argument by using the {\bf :default-initargs} class option. If an
initialization argument is declared valid by a class, its default
value form is usually specified by a class other than the class that
declared its validity. Thus, in this case {\bf :default-initargs} is
usually used to supply a default value for an inherited initialization
argument.
The argument to the {\bf :default-initargs} class option is a list of
alternating initialization argument names and forms. Each form is the
default value form for the corresponding initialization argument. The
default value form of an initialization argument is used only if that
initialization argument does not appear in the arguments to {\bf
make-instance}. In that case, the default value form is evaluated in
the lexical environment of the {\bf defclass} form that supplied it,
and the resulting value is used as the initialization argument's
value.
The initialization arguments supplied to {\bf make-instance} are combined
with defaulted initialization arguments to produce a {\bit
defaulted initialization argument list}. A defaulted initialization
argument list is a list of alternating initialization argument names and
values in which unsupplied initialization arguments are defaulted and in
which the explicitly supplied initialization arguments appear earlier in
the list than the defaulted initialization arguments. Defaulted
initialization arguments are ordered according to the order in the class
precedence list of the classes that supplied the default values.
The {\bf :default-initargs} option is used only to provide default values
for initialization arguments; it does not declare a symbol as a valid
initialization argument name.
There is a distinction between the purposes of the {\bf
:default-initargs} and the {\bf :initform} options with respect to the
initialization of slots. The {\bf :default-initargs} class option
allows the user to give a default value form for an initialization
argument without knowing whether the initialization argument
initializes a slot. If that initialization argument is not explicitly
supplied in a call to {\bf make-instance}, the default value form is
used, just as if it had been supplied in the call. In contrast, the
{\bf :initform} slot option allows the user to give a default initial
value form for a slot. An {\bf :initform} form is used only if no
initialization argument associated with that slot is given as an
argument to {\bf make-instance} or defaulted by {\bf
:default-initargs}.
The \OS\ does not guarantee any given order of evaluation of default value
and {\bf :initform} forms. If the order of evaluation is important, {\bf
initialize-instance} methods should be used instead. It is not
recommended that {\bf :initform} forms or default value forms have
side-effects other than creating new objects.
\endsubSection%{Defaulting of Initialization Arguments}
\beginsubSection{Rules for Duplicate Initialization Arguments}
The following rules specify what happens when initialization arguments are
duplicated.
\beginlist
\item{\bull} The {\bf :initarg} slot option may be specified more than
once for a given slot.
\item{\bull} It is valid for a single initialization argument to
initialize more than one slot if the same initialization argument name
appears in more than one {\bf :initarg} slot option.
\item{\bull} It is valid for a single initialization argument to appear
in the lambda-list of more than one initialization method.
\item{\bull} It is valid for a given initialization argument name to
appear both in an {\bf :initarg} slot option and in the lambda-list
of an initialization method.
\item{\bull} If two initialization arguments that initialize the same slot
are given in the arguments to {\bf make-instance}, the leftmost of these
initialization arguments in the initialization argument list prevails,
even if the two initialization arguments have different names. This
behavior is consistent with the behavior of property lists and with the
portion of an argument list processed for {\bf \&key} parameters.
\item{\bull} If two different initialization arguments that initialize the
same slot have default values, and neither is given explicitly in the
arguments to {\bf make-instance}, the initialization argument that appears
in a {\bf :default-initargs} class option in the more specific of the two
classes prevails. If they appear in the same class, the one whose mention
is leftmost in the {\bf defclass} form prevails. During the defaulting of
initialization arguments, the defaults are appended to the end of the
initialization argument list in this order.
\item{\bull} If there are two different initialization arguments that
initialize the same slot, and one was given explicitly in the arguments to
{\bf make-instance} while the other was defaulted using {\bf
:default-initargs}, the explicit one prevails. This follows from the
previous two rules.
\item{\bull} If a slot has both an {\bf :initform} and an {\bf :initarg}
slot option, and the initialization argument is defaulted using {\bf
:default-initargs}, the {\bf :initform} form is neither used nor
evaluated.
\endlist
The following is an example of the above rules:
\screen!
(defclass a () ((x :initarg a)))
(defclass b (a) ((x :initarg b))
(:default-initargs a 1 b 2))
\endscreen!
$$\vbox{\halign{\strut#\hfil&\quad\hfil#\hfil&\quad\hfil#\hfil\cr
{}&\bf Defaulted&{}\cr
\bf Form&\bf Initialization Argument List&\bf Contents of Slot X\cr
\noalign{\hrule}
{\tt (make-instance 'b)}&{\tt (a 1 b 2)}&{\tt 1}\cr
{\tt (make-instance 'b 'a 3)}&{\tt (a 3 b 2)}&{\tt 3}\cr
{\tt (make-instance 'b 'b 4)}&{\tt (b 4 a 1)}&{\tt 4}\cr
{\tt (make-instance 'b 'a 1 'a 2)}&{\tt (a 1 a 2 b 2)}&{\tt 1}\cr}}$$
\endsubSection%{Rules for Duplication of Initialization arguments}
\beginsubSection{Methods for Initialize-instance}
The generic function {\bf initialize-instance} uses standard method
combination. Methods for {\bf initialize-instance} can be defined in
order to perform any initialization that cannot be achieved with the
simple slot-filling mechanisms.
During initialization, {\bf initialize-instance} is invoked
after the following actions have been taken:
\beginlist
\item{\bull} The defaulted initialization argument list is computed by
combining the supplied initialization argument list with any default
initialization arguments for the class.
\item{\bull} The validity of the defaulted initialization argument list is
checked. If any of the initialization arguments has not been declared as
valid, an error is signaled.
\item{\bull} A new instance whose slots are uninitialized is created.
\endlist
The generic function {\bf initialize-instance} is then called with the
new instance and the defaulted initialization argument list. The
system-supplied default method is a primary method that initializes the
slots with values according to the initialization argument list. This
default method behaves as follows on each slot, whether shared or local:
\beginlist
\item{\bull} If an initialization argument in the defaulted
initialization argument list specifies a value for that slot, that
value is stored into the slot. This occurs even if a value has already been
stored in the slot before the default method is run. A {\bf :before}
or an {\bf :around} method, for example, might store a value in the
slot.
\item{\bull} Otherwise, if the slot is uninitialized and has an {\bf
:initform} form, that form is evaluated and the result is stored into the
slot.
\item{\bull} The duplicate-resolution rules mentioned in the section
``Rules for Duplicate Initialization Arguments'' are obeyed.
\endlist
User-defined {\bf :after} methods can be used to customize
this step of the initialization process because they will be run
after the default activities of {\bf initialize-instance}.
Care should be taken to not supply primary methods
that override the default primary method unless the default activities
of {\bf initialize-instance} are not desired.
The \OS\ provides two functions that are useful in the bodies of {\bf
initialize-instance} methods. The function {\bf slot-boundp} returns a
boolean value that states whether the slot has a value; this enables
writing {\bf :after} methods for {\bf initialize-instance} that initialize
slots only if they have not already been initialized. The function {\bf
slot-makunbound} restores a slot to the uninitialized state.
\endsubSection%{Methods for INITIALIZE-INSTANCE }
\beginsubSection{Procedural Definition of Make-instance}
The generic function {\bf make-instance} behaves as if it were defined as
follows, except that certain optimizations are permitted:
\screen!
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(check-initargs class initargs)
(let ((instance (apply #'allocate-instance class initargs)))
(apply #'initialize-instance instance initargs)
instance))
(defmethod make-instance ((class-name symbol) &rest initargs)
(apply #'make-instance (symbol-class class-name) initargs))
\endscreen!
This procedure can be customized at either the Programmer Interface level,
the Meta-object level, or both.
Customizing at the Programmer Interface level includes using the {\bf
:initform}, {\bf :initarg}, and {\bf :default-initargs} options to {\bf
defclass}, as well as defining methods for {\bf initialize-instance}. The
meta-object level supports extra customization by defining methods for
{\bf make-instance}, {\bf default-initargs}, {\bf check-initargs}, and
{\bf allocate-instance}. Chapters~2 and~3 document each of these generic
functions and the system-supplied default methods.
Implementations are permitted to make certain optimizations of {\bf
initialize-instance}. The description of {\bf initialize-instance} in
Chapter~2 mentions the possible optimizations.
Because of optimization, methods for the meta-object generic functions
listed may not actually be called on every call to {\bf make-instance}
or may not receive exactly the arguments that would be expected. For
example, {\bf check-initargs} might actually be called before {\bf
default-initargs} rather than after, if it has already been determined
that the default initialization arguments will be approved by {\bf
check-initargs}.
\endsubSection%{Procedural Definition of MAKE-INSTANCE}
\endSection%{Object Creation and Initialization}
\beginSection{Introduction to Setf Functions}
This section is an introduction to setf functions, which are generalized
in the \CLOS\ to setf generic functions.
A {\bit setf function\/} is called in an expression such as the
following:
$$\hbox{{\tt (setf ({\it name . arguments}) {\it new-value})}}$$
A setf function can be defined by using a name of the form {\tt
(setf {\it name})}. There is an automatic association between the
setf function named {\tt (setf {\it name})} and the function named
{\it name} as follows:
The macroexpansion of the {\bf setf} form {\tt (setf ({\it name}
$x\sub 1\ldots x\sub n$) {\it new-value\/})} obeys the following
rules, where the first rule that applies supercedes any later ones:
\beginlist
\item{\bull}If {\it name} refers to the global function definition,
rather than to a locally defined function or macro, and if there is a
{\bf setf} macro defined for {\it name}, the {\bf setf} macro is used to
compute the expansion.
\item{\bull} If {\it name} is defined as a macro in the current scope,
{\bf macroexpand-1} is used to expand \hbox{{\tt ({\it name} $x\sub 1\ldots
x\sub n$)}}, and the resulting expansion is macroexpanded again.
\item{\bull} If {\it name} is defined as a special form in the current
scope, an error is signaled.
\item{\bull} The {\bf setf} form is expanded into the equivalent of
\endlist
$$\openup1\jot\vbox{\settabs\+\cr
\+{\tt(}& {\tt let} &{\tt (}& {\tt (}{\tt\#:tem}&{\tt p-1} $x\sub 1${\tt)}\cr
\+&&&&$\vdots$\cr
\+&&&{\tt(\#:temp-}$n$ $x\sub n${\tt))}\cr
\+&{\tt(funcall} {\tt\#'(setf} {\it name}{\tt)} {\it new-value} {\tt\#:temp-1} $\ldots$ {\tt\#:temp-}$n${\tt))}\cr}$$
\endSection%{Introduction to Setf Functions}
\endChapter
\bye